home *** CD-ROM | disk | FTP | other *** search
- /*--------------------------------------------------------------------------*/
- /* */
- /* */
- /* ------------ Bit-Bucket Software <no-Inc> */
- /* \ 10001101 / Writers and Distributors of */
- /* \ 011110 / No-Cost<no-tm> Software. */
- /* \ 1011 / */
- /* ------ */
- /* */
- /* Copyright (C) 1987, 1988, 1989 by Robert Hartman and Vincent Perriello */
- /* */
- /* */
- /* Zmodem file transmission module */
- /* */
- /* */
- /* For complete details of the licensing restrictions, please refer */
- /* to the License agreement, which is published in its entirety in */
- /* the MAKEFILE and BT.C, and also contained in the file LICENSE.210. */
- /* */
- /* USE OF THIS FILE IS SUBJECT TO THE RESTRICTIONS CONTAINED IN THE */
- /* BINKLEYTERM LICENSING AGREEMENT. IF YOU DO NOT FIND THE TEXT OF */
- /* THIS AGREEMENT IN ANY OF THE AFOREMENTIONED FILES, OR IF YOU DO */
- /* NOT HAVE THESE FILES, YOU SHOULD IMMEDIATELY CONTACT THE AUTHORS */
- /* AT THE ADDRESSES LISTED BELOW. IN NO EVENT SHOULD YOU PROCEED TO */
- /* USE THIS FILE WITHOUT HAVING ACCEPTED THE TERMS OF THE */
- /* BINKLEYTERM LICENSING AGREEMENT, OR SUCH OTHER AGREEMENT AS YOU */
- /* ARE ABLE TO REACH WITH THE AUTHORS. */
- /* */
- /* */
- /* The Authors can be reached at the following addresses: */
- /* */
- /* Robert C. Hartman Vincent E. Perriello */
- /* Spark Software VEP Software */
- /* 427-3 Amherst Street 111 Carroll Street */
- /* CS2032, Suite 232 Naugatuck, CT 06770 */
- /* Nashua, NH 03061 */
- /* */
- /* FidoNet 1:132/101 FidoNet 1:141/491 */
- /* Data (603) 888-8179 Data (203) 729-7569 */
- /* */
- /* Please feel free to contact us at any time to share your comments */
- /* about our software and/or licensing policies. */
- /* */
- /* */
- /* This module is based largely on a similar module in OPUS-CBCS V1.03b. */
- /* The original work is (C) Copyright 1986, Wynn Wagner III. The original */
- /* authors have graciously allowed us to use their code in this work. */
- /* */
- /*--------------------------------------------------------------------------*/
-
-
- #include <time.h>
- #include <io.h>
- #include <stdlib.h>
- #include <conio.h>
- #include <string.h>
-
- #include "com.h"
- #include "xfer.h"
- #include "zmodem.h"
- #include "keybd.h"
- #include "sbuf.h"
- #include "sched.h"
- #include "externs.h"
- #include "prototyp.h"
-
-
- /*--------------------------------------------------------------------------*/
- /* Private routines */
- /*--------------------------------------------------------------------------*/
- static void ZS_SendBinaryHeader (unsigned short, byte *);
- static void ZS_32SendBinaryHeader (unsigned short, byte *);
- static void ZS_SendData (byte *, int, unsigned short);
- static void ZS_32SendData (byte *, int, unsigned short);
- static void ZS_SendByte (byte);
- static int ZS_GetReceiverInfo (void);
- static int ZS_SendFile (int, int);
- static int ZS_SendFileData (int);
- static int ZS_SyncWithReceiver (int);
- static void ZS_EndSend (void);
-
- /*--------------------------------------------------------------------------*/
- /* Private data */
- /*--------------------------------------------------------------------------*/
- static FILE *Infile; /* Handle of file being sent*/
- static long Strtpos; /* Starting byte position of*/
- /* download */
- static long LastZRpos; /* Last error location */
- static long ZRPosCount; /* ZRPOS repeat count */
- static long Txpos; /* Transmitted file position*/
- static int Rxbuflen; /* Receiver's max buffer */
- /* length */
- static int Rxflags; /* Receiver's flags */
-
- /*--------------------------------------------------------------------------*/
- /* SEND ZMODEM (send a file) */
- /* returns TRUE (1) for good xfer, FALSE (0) for bad */
- /* sends one file per call; 'fsent' flags start and end of batch */
- /*--------------------------------------------------------------------------*/
- int Send_Zmodem (fname, alias, fsent, wazoo)
- char *fname;
- char *alias;
- int fsent;
- int wazoo;
- {
- register byte *p;
- register byte *q;
- struct stat f;
- int i;
- int rc;
- char j[100];
-
- #ifdef DEBUG
- show_debug_name ("send_Zmodem");
- #endif
-
- _BRK_DISABLE ();
- IN_XON_ENABLE ();
-
- errno =
- z_size = 0;
- Infile = NULL;
- /* Txbuf = NULL;*/
-
- if (fname && !(fullscreen && un_attended))
- set_xy ("");
-
- switch (fsent)
- {
- case 0:
- case NOTHING_TO_DO:
- if (!wazoo)
- {
- Z_PutString ("rz\r");
- Z_PutLongIntoHeader (0L);
- Z_SendHexHeader (ZRQINIT, Txhdr);
- }
- Rxtimeout = 200;
- if (ZS_GetReceiverInfo () == ERROR)
- {
- XON_DISABLE ();
- XON_ENABLE ();
- return FALSE;
- }
- }
-
- Rxtimeout = (int) (614400L / (long) cur_baud);
-
- if (Rxtimeout < 100)
- Rxtimeout = 100;
-
- if (fname == NULL)
- goto Done;
-
- /*--------------------------------------------------------------------*/
- /* Prepare the file for transmission. Just ignore file open errors */
- /* because there may be other files that can be sent. */
- /*--------------------------------------------------------------------*/
- Filename = fname;
- CLEAR_IOERR ();
- Infile = fopen (Filename, read_binary);
- if (got_error (OPEN_msg, Filename))
- {
- XON_DISABLE ();
- XON_ENABLE ();
- return OK;
- }
- if (isatty (fileno (Infile)))
- {
- errno = 1;
- got_error (DEVICE_msg, Filename);
- fclose (Infile);
- XON_DISABLE ();
- XON_ENABLE ();
- return OK;
- }
-
- /* Txbuf = zalloc ();*/
-
- /*--------------------------------------------------------------------*/
- /* Send the file */
- /*--------------------------------------------------------------------*/
- rc = TRUE;
-
- /*--------------------------------------------------------------------*/
- /* Display outbound filename, size, and ETA for sysop */
- /*--------------------------------------------------------------------*/
- fstat (fileno (Infile), &f);
-
- i = (int) (f.st_size * 10 / cur_baud + 27) / 54;
- sprintf (j, "Z-Send %s, %ldb, %d min.", Filename, f.st_size, i);
-
- if (un_attended && fullscreen)
- {
- clear_filetransfer ();
- sb_move (filewin, 1, 2);
- sb_puts (filewin, j);
- sb_show ();
- }
- else
- {
- cprintf ("%s", j);
- set_xy (NULL);
- locate_x += 2;
- }
-
-
- /*--------------------------------------------------------------------*/
- /* Get outgoing file name; no directory path, lower case */
- /*--------------------------------------------------------------------*/
- for (p = (alias != NULL) ? alias : Filename, q = Txbuf; *p;)
- {
- if ((*q++ = tolower (*p)) == '\\')
- q = Txbuf;
- p++;
- }
-
- *q++ = '\0';
- p = q;
-
- /*--------------------------------------------------------------------*/
- /* Zero out remainder of file header packet */
- /*--------------------------------------------------------------------*/
- while (q < (Txbuf + KSIZE))
- *q++ = '\0';
-
- /*--------------------------------------------------------------------*/
- /* Store filesize, time last modified, and file mode in header packet */
- /*--------------------------------------------------------------------*/
- sprintf (p, "%lu %lo %o", f.st_size, f.st_mtime, f.st_mode);
-
- /*--------------------------------------------------------------------*/
- /* Transmit the filename block and { the download */
- /*--------------------------------------------------------------------*/
- throughput (0, 0L);
-
- /*--------------------------------------------------------------------*/
- /* Check the results */
- /*--------------------------------------------------------------------*/
- switch (ZS_SendFile (1 + strlen (p) + (p - Txbuf), wazoo))
- {
- case ERROR:
- /*--------------------------------------------------*/
- /* Something tragic happened */
- /*--------------------------------------------------*/
- goto Err_Out;
-
- case OK:
- /*--------------------------------------------------*/
- /* File was sent */
- /*--------------------------------------------------*/
- CLEAR_IOERR ();
- fclose (Infile);
- got_error (CLOSE_msg, Filename);
- Infile = NULL;
-
- status_line ("+Sent-Z%s %s", Crc32t ? "/32" : "", Filename);
-
- update_files (1);
- goto Done;
-
- case ZSKIP:
- status_line ("+Remote refused %s", Filename);
- rc = SPEC_COND; /* Success but don't truncate! */
- goto Done;
-
- default:
- /*--------------------------------------------------*/
- /* Ignore the problem, get next file, trust other */
- /* error handling mechanisms to deal with problems */
- /*--------------------------------------------------*/
- goto Done;
- } /* switch */
-
- Err_Out:
- rc = FALSE;
-
- Done:
- if (Infile)
- fclose (Infile);
- /*
- if (Txbuf)
- free (Txbuf);
- */
- if (fsent < 0)
- ZS_EndSend ();
-
- XON_DISABLE ();
- XON_ENABLE ();
-
- return rc;
- } /* send_Zmodem */
-
- /*--------------------------------------------------------------------------*/
- /* ZS SEND BINARY HEADER */
- /* Send ZMODEM binary header hdr of type type */
- /*--------------------------------------------------------------------------*/
- static void ZS_SendBinaryHeader (type, hdr)
- unsigned short type;
- register byte *hdr;
- {
- register unsigned short crc;
- int n;
-
- #ifdef DEBUG
- show_debug_name ("ZS_SendBinaryHeader");
- #endif
-
- BUFFER_BYTE (ZPAD);
- BUFFER_BYTE (ZDLE);
-
- if (Crc32t = Txfcs32)
- ZS_32SendBinaryHeader (type, hdr);
- else
- {
- BUFFER_BYTE (ZBIN);
- ZS_SendByte ((byte) type);
-
- crc = Z_UpdateCRC (type, 0);
-
- for (n = 4; --n >= 0;)
- {
- ZS_SendByte (*hdr);
- crc = Z_UpdateCRC (((unsigned short) (*hdr++)), crc);
- }
- ZS_SendByte ((byte) (crc >> 8));
- ZS_SendByte ((byte) crc);
-
- UNBUFFER_BYTES ();
- }
-
- if (type != ZDATA)
- {
- while (CARRIER && !OUT_EMPTY ())
- time_release ();
- if (!CARRIER)
- CLEAR_OUTBOUND ();
- }
- } /* ZS_SendBinaryHeader */
-
- /*--------------------------------------------------------------------------*/
- /* ZS SEND BINARY HEADER */
- /* Send ZMODEM binary header hdr of type type */
- /*--------------------------------------------------------------------------*/
- static void ZS_32SendBinaryHeader (type, hdr)
- unsigned short type;
- register byte *hdr;
- {
- unsigned long crc;
- int n;
-
- #ifdef DEBUG
- show_debug_name ("ZS_32SendBinaryHeader");
- #endif
-
- BUFFER_BYTE (ZBIN32);
- ZS_SendByte ((byte) type);
-
- crc = 0xFFFFFFFF;
- crc = Z_32UpdateCRC (type, crc);
-
- for (n = 4; --n >= 0;)
- {
- ZS_SendByte (*hdr);
- crc = Z_32UpdateCRC (((unsigned short) (*hdr++)), crc);
- }
-
- crc = ~crc;
- for (n = 4; --n >= 0;)
- {
- ZS_SendByte ((byte) crc);
- crc >>= 8;
- }
-
- UNBUFFER_BYTES ();
- } /* ZS_SendBinaryHeader */
-
- /*--------------------------------------------------------------------------*/
- /* ZS SEND DATA */
- /* Send binary array buf with ending ZDLE sequence frameend */
- /*--------------------------------------------------------------------------*/
- static void ZS_SendData (buf, length, frameend)
- register byte *buf;
- int length;
- unsigned short frameend;
- {
- register unsigned short crc;
-
- #ifdef DEBUG
- show_debug_name ("ZS_SendData");
- #endif
-
- if (Crc32t)
- ZS_32SendData (buf, length, frameend);
- else
- {
- crc = 0;
- for (; --length >= 0;)
- {
- ZS_SendByte (*buf);
- crc = Z_UpdateCRC (((unsigned short) (*buf++)), crc);
- }
-
- BUFFER_BYTE (ZDLE);
- BUFFER_BYTE ((unsigned char) frameend);
- crc = Z_UpdateCRC (frameend, crc);
- ZS_SendByte ((byte) (crc >> 8));
- ZS_SendByte ((byte) crc);
-
- UNBUFFER_BYTES ();
-
- }
-
- if (frameend == ZCRCW)
- {
- SENDBYTE (XON);
- while (CARRIER && !OUT_EMPTY ())
- time_release ();
- if (!CARRIER)
- CLEAR_OUTBOUND ();
- }
- } /* ZS_SendData */
-
- /*--------------------------------------------------------------------------*/
- /* ZS SEND DATA with 32 bit CRC */
- /* Send binary array buf with ending ZDLE sequence frameend */
- /*--------------------------------------------------------------------------*/
- static void ZS_32SendData (buf, length, frameend)
- register byte *buf;
- int length;
- unsigned short frameend;
- {
- unsigned long crc;
-
- #ifdef DEBUG
- show_debug_name ("ZS_32SendData");
- #endif
-
- crc = 0xFFFFFFFF;
- for (; --length >= 0; ++buf)
- {
- ZS_SendByte (*buf);
- crc = Z_32UpdateCRC (((unsigned short) (*buf)), crc);
- }
-
- BUFFER_BYTE (ZDLE);
- BUFFER_BYTE ((unsigned char) frameend);
- crc = Z_32UpdateCRC (frameend, crc);
-
- crc = ~crc;
-
- for (length = 4; --length >= 0;)
- {
- ZS_SendByte ((byte) crc);
- crc >>= 8;
- }
-
- UNBUFFER_BYTES ();
-
- } /* ZS_SendData */
-
- /*--------------------------------------------------------------------------*/
- /* ZS SEND BYTE */
- /* Send character c with ZMODEM escape sequence encoding. */
- /* Escape XON, XOFF. Escape CR following @ (Telenet net escape) */
- /*--------------------------------------------------------------------------*/
- static void ZS_SendByte (c)
- register byte c;
- {
- static byte lastsent;
-
- switch (c)
- {
- case 015:
- case 0215:
- if ((lastsent & 0x7F) != '@')
- goto SendIt;
- case 020:
- case 021:
- case 023:
- case 0220:
- case 0221:
- case 0223:
- case ZDLE:
- /*--------------------------------------------------*/
- /* Quoted characters */
- /*--------------------------------------------------*/
- BUFFER_BYTE (ZDLE);
- c ^= 0x40;
-
- default:
- /*--------------------------------------------------*/
- /* Normal character output */
- /*--------------------------------------------------*/
- SendIt:
- BUFFER_BYTE (lastsent = c);
-
- } /* switch */
- } /* ZS_SendByte */
-
- /*--------------------------------------------------------------------------*/
- /* ZS GET RECEIVER INFO */
- /* Get the receiver's init parameters */
- /*--------------------------------------------------------------------------*/
- static int ZS_GetReceiverInfo ()
- {
- int n;
-
- #ifdef DEBUG
- show_debug_name ("ZS_GetReceiverInfo");
- #endif
-
- for (n = 10; --n >= 0;)
- {
- switch (Z_GetHeader (Rxhdr))
- {
- case ZCHALLENGE:
- /*--------------------------------------*/
- /* Echo receiver's challenge number */
- /*--------------------------------------*/
- Z_PutLongIntoHeader (Rxpos);
- Z_SendHexHeader (ZACK, Txhdr);
- continue;
-
- case ZCOMMAND:
- /*--------------------------------------*/
- /* They didn't see our ZRQINIT */
- /*--------------------------------------*/
- Z_PutLongIntoHeader (0L);
- Z_SendHexHeader (ZRQINIT, Txhdr);
- continue;
-
- case ZRINIT:
- /*--------------------------------------*/
- /* */
- /*--------------------------------------*/
- Rxflags = 0377 & Rxhdr[ZF0];
- Rxbuflen = ((word) Rxhdr[ZP1] << 8) | Rxhdr[ZP0];
- Txfcs32 = Rxflags & CANFC32;
- return OK;
-
- case ZCAN:
- case RCDO:
- case TIMEOUT:
- return ERROR;
-
- case ZRQINIT:
- if (Rxhdr[ZF0] == ZCOMMAND)
- continue;
-
- default:
- Z_SendHexHeader (ZNAK, Txhdr);
- continue;
- } /* switch */
- } /* for */
-
- return ERROR;
- } /* ZS_GetReceiverInfo */
-
- /*--------------------------------------------------------------------------*/
- /* ZS SEND FILE */
- /* Send ZFILE frame and begin sending ZDATA frame */
- /*--------------------------------------------------------------------------*/
- static int ZS_SendFile (blen, wazoo)
- int blen;
- int wazoo;
- {
- register int c;
- long t, timerset ();
-
- #ifdef DEBUG
- show_debug_name ("ZS_SendFile");
- #endif
-
- while (1)
- {
- if (got_ESC ())
- {
- CLEAR_OUTBOUND ();
- XON_DISABLE (); /* Make sure xmitter is
- * unstuck */
- send_can (); /* transmit at least 10 cans */
- t = timerset (200); /* wait no more than 2
- * seconds */
- while (!timeup (t) && !OUT_EMPTY () && CARRIER)
- time_release (); /* Give up slice while
- * waiting */
- XON_ENABLE (); /* Turn XON/XOFF back on... */
- z_log (KBD_msg);
- return ERROR;
- }
- else if (!CARRIER)
- return ERROR;
-
- Txhdr[ZF0] = LZCONV; /* Default file conversion
- * mode */
- Txhdr[ZF1] = LZMANAG; /* Default file management
- * mode */
- Txhdr[ZF2] = LZTRANS; /* Default file transport
- * mode */
- Txhdr[ZF3] = 0;
- ZS_SendBinaryHeader (ZFILE, Txhdr);
- ZS_SendData (Txbuf, blen, ZCRCW);
-
- Again:
- switch (c = Z_GetHeader (Rxhdr))
- {
- case ZRINIT:
- while ((c = Z_GetByte (50)) > 0)
- if (c == ZPAD)
- goto Again;
-
- /* Fall thru to */
-
- default:
- continue;
-
- case ZCAN:
- case RCDO:
- case TIMEOUT:
- case ZFIN:
- case ZABORT:
- return ERROR;
-
- case ZSKIP:
- /*-----------------------------------------*/
- /* Other system wants to skip this file */
- /*-----------------------------------------*/
- return c;
-
- case ZRPOS:
- /*-----------------------------------------*/
- /* Resend from this position... */
- /*-----------------------------------------*/
- fseek (Infile, Rxpos, SEEK_SET);
- if (Rxpos != 0L)
- {
- status_line (":Resuming from offset %ld", Rxpos);
- CLEAR_OUTBOUND (); /* Get rid of queued data */
- XON_DISABLE (); /* End XON/XOFF restraint */
- SENDBYTE (XON); /* Send XON to remote */
- XON_ENABLE (); /* Start XON/XOFF again */
- }
- LastZRpos = Strtpos = Txpos = Rxpos;
- ZRPosCount = 10;
- CLEAR_INBOUND ();
- return ZS_SendFileData (wazoo);
- } /* switch */
- } /* while */
- } /* ZS_SendFile */
-
- /*--------------------------------------------------------------------------*/
- /* ZS SEND FILE DATA */
- /* Send the data in the file */
- /*--------------------------------------------------------------------------*/
- static int ZS_SendFileData (wazoo)
- int wazoo;
- {
- register int c, e;
- word newcnt, blklen, maxblklen, goodblks, goodneeded = 1;
-
- long t, timerset ();
-
- #ifdef DEBUG
- show_debug_name ("ZS_SendFileData");
- #endif
-
- maxblklen = (cur_baud < 300) ? 128 : cur_baud / 300 * 256;
-
- if (maxblklen > WAZOOMAX)
- maxblklen = WAZOOMAX;
- if (!wazoo && maxblklen > KSIZE)
- maxblklen = KSIZE;
- if (Rxbuflen && maxblklen > Rxbuflen)
- maxblklen = Rxbuflen;
- blklen = maxblklen;
-
- SomeMore:
-
- if (CHAR_AVAIL ())
- {
- WaitAck:
-
- switch (c = ZS_SyncWithReceiver (1))
- {
- case ZSKIP:
- /*-----------------------------------------*/
- /* Skip this file */
- /*-----------------------------------------*/
- return c;
-
- case ZACK:
- break;
-
- case ZRPOS:
- /*-----------------------------------------*/
- /* Resume at this position */
- /*-----------------------------------------*/
- blklen = ((blklen >> 2) > 64) ? blklen >> 2 : 64;
- goodblks = 0;
- goodneeded = ((goodneeded << 1) > 16) ? 16 : goodneeded << 1;
- break;
-
- case ZRINIT:
- /*-----------------------------------------*/
- /* Receive init */
- /*-----------------------------------------*/
- if (locate_y && !(fullscreen && un_attended))
- gotoxy (2, (byte) locate_y - 1);
- throughput (1, Txpos - Strtpos);
- return OK;
-
- case TIMEOUT:
- /*-----------------------------------------*/
- /* Timed out on message from other side */
- /*-----------------------------------------*/
- break;
-
- default:
- z_log (Cancelled_msg);
- errno = 0;
- fclose (Infile);
- got_error (CLOSE_msg, Filename);
- return ERROR;
- } /* switch */
-
- /*
- * Noise probably got us here. Odds of surviving are not good. But we
- * have to get unstuck in any event.
- *
- */
-
- Z_UncorkTransmitter (); /* Get our side free if need
- * be */
- SENDBYTE (XON); /* Send an XON to release
- * other side */
-
- while (CHAR_AVAIL ())
- {
- switch (MODEM_IN ())
- {
- case CAN:
- case RCDO:
- case ZPAD:
- goto WaitAck;
- } /* switch */
- } /* while */
- } /* while */
-
- newcnt = Rxbuflen;
- Z_PutLongIntoHeader (Txpos);
- ZS_SendBinaryHeader (ZDATA, Txhdr);
-
- do
- {
- if (((KEYPRESS ()) && (READKB () == 27)))
- {
- CLEAR_OUTBOUND ();
- XON_DISABLE (); /* Make sure xmitter is
- * unstuck */
- send_can (); /* transmit at least 10 cans */
- t = timerset (200); /* wait no more than 2
- * seconds */
- while (!timeup (t) && !OUT_EMPTY () && CARRIER)
- time_release (); /* Give up slice while
- * waiting */
- XON_ENABLE (); /* Turn XON/XOFF back on... */
- z_log (KBD_msg);
- goto oops;
- }
-
- if (!CARRIER)
- goto oops;
-
- if ((c = fread (Txbuf, 1, blklen, Infile)) != z_size)
- {
- if (fullscreen && un_attended)
- {
- sb_move (filewin, 2, 12);
- sb_puts (filewin, ultoa (((unsigned long) (z_size = c)), e_input, 10));
- sb_puts (filewin, " ");
- sb_show ();
- }
- else
- {
- gotoxy (locate_x + 10, locate_y);
- cputs (ultoa (((unsigned long) (z_size = c)), e_input, 10));
- putch (' ');
- }
- }
-
- if (c < blklen)
- e = ZCRCE;
- else if (Rxbuflen && (newcnt -= c) <= 0)
- e = ZCRCW;
- else e = ZCRCG;
-
- ZS_SendData (Txbuf, c, e);
-
- if (fullscreen && un_attended)
- {
- sb_move (filewin, 2, 2);
- sb_puts (filewin, ultoa (((unsigned long) Txpos), e_input, 10));
- sb_puts (filewin, " ");
- sb_show ();
- }
- else
- {
- gotoxy (locate_x, locate_y);
- cputs (ultoa (((unsigned long) Txpos), e_input, 10));
- putch (' ');
- putch (' ');
- }
-
- Txpos += c;
- if (blklen < maxblklen && ++goodblks > goodneeded)
- {
- blklen = ((blklen << 1) < maxblklen) ? blklen << 1 : maxblklen;
- goodblks = 0;
- }
-
- if (e == ZCRCW)
- goto WaitAck;
-
- while (CHAR_AVAIL ())
- {
- switch (MODEM_IN ())
- {
- case CAN:
- case RCDO:
- case ZPAD:
- /*--------------------------------------*/
- /* Interruption detected; */
- /* stop sending and process complaint */
- /*--------------------------------------*/
- z_message ("Trouble?");
- CLEAR_OUTBOUND ();
- ZS_SendData (Txbuf, 0, ZCRCE);
- goto WaitAck;
- } /* switch */
- } /* while */
-
- } /* do */
- while (e == ZCRCG);
-
- while (1)
- {
- Z_PutLongIntoHeader (Txpos);
- ZS_SendBinaryHeader (ZEOF, Txhdr);
-
- switch (ZS_SyncWithReceiver (7))
- {
- case ZACK:
- continue;
-
- case ZRPOS:
- /*-----------------------------------------*/
- /* Resume at this position... */
- /*-----------------------------------------*/
- goto SomeMore;
-
- case ZRINIT:
- /*-----------------------------------------*/
- /* Receive init */
- /*-----------------------------------------*/
- if (locate_y && !(fullscreen && un_attended))
- gotoxy (2, (byte) locate_y - 1);
- throughput (1, Txpos - Strtpos);
- return OK;
-
- case ZSKIP:
- /*-----------------------------------------*/
- /* Request to skip the current file */
- /*-----------------------------------------*/
- z_log (Skip_msg);
- CLEAR_IOERR ();
- fclose (Infile);
- got_error (CLOSE_msg, Filename);
- return c;
-
- default:
- oops:
- z_log (Cancelled_msg);
- errno = 0;
- fclose (Infile);
- got_error (CLOSE_msg, Filename);
- return ERROR;
- } /* switch */
- } /* while */
- } /* ZS_SendFileData */
-
- /*--------------------------------------------------------------------------*/
- /* ZS SYNC WITH RECEIVER */
- /* Respond to receiver's complaint, get back in sync with receiver */
- /*--------------------------------------------------------------------------*/
- static int ZS_SyncWithReceiver (num_errs)
- int num_errs;
- {
- register int c;
- char j[50];
-
- #ifdef DEBUG
- show_debug_name ("ZS_SyncWithReceiver");
- #endif
- while (1)
- {
- c = Z_GetHeader (Rxhdr);
- CLEAR_INBOUND ();
- switch (c)
- {
- case TIMEOUT:
- z_message (TIME_msg);
- if ((num_errs--) >= 0)
- break;
-
- case ZCAN:
- case ZABORT:
- case ZFIN:
- case RCDO:
- z_log ("!Err");
- return ERROR;
-
- case ZRPOS:
- if (Rxpos == LastZRpos) /* Same as last time? */
- {
- if (!(--ZRPosCount)) /* Yup, 10 times yet? */
- return ERROR; /* Too many, get out */
- }
- else ZRPosCount = 10; /* Reset repeat count */
- LastZRpos = Rxpos; /* Keep track of this */
-
- rewind (Infile); /* In case file EOF seen */
- fseek (Infile, Rxpos, SEEK_SET);
- Txpos = Rxpos;
- sprintf (j, "Resending from %s",
- ultoa (((unsigned long) (Txpos)), e_input, 10));
- z_message (j);
- return c;
-
- case ZSKIP:
- z_log (Skip_msg);
-
- case ZRINIT:
- CLEAR_IOERR ();
- fclose (Infile);
- got_error (CLOSE_msg, Filename);
- return c;
-
- case ZACK:
- z_message (NULL);
- return c;
-
- default:
- z_message (IDUNNO_msg);
- ZS_SendBinaryHeader (ZNAK, Txhdr);
- continue;
- } /* switch */
- } /* while */
- } /* ZS_SyncWithReceiver */
-
-
-
-
- /*--------------------------------------------------------------------------*/
- /* ZS END SEND */
- /* Say BIBI to the receiver, try to do it cleanly */
- /*--------------------------------------------------------------------------*/
- static void ZS_EndSend ()
- {
-
- #ifdef DEBUG
- show_debug_name ("ZS_EndSend");
- #endif
-
- while (1)
- {
- Z_PutLongIntoHeader (0L);
- ZS_SendBinaryHeader (ZFIN, Txhdr);
-
- switch (Z_GetHeader (Rxhdr))
- {
- case ZFIN:
- SENDBYTE ('O');
- SENDBYTE ('O');
- while (CARRIER && !OUT_EMPTY ())
- time_release ();
- if (!CARRIER)
- CLEAR_OUTBOUND ();
- /* fallthrough... */
- case ZCAN:
- case RCDO:
- case TIMEOUT:
- return;
- } /* switch */
- } /* while */
- } /* ZS_EndSend */
-
-
- /* END OF FILE: zsend.c */